"""
	The Collection class controls the music library as defined by the user. with this
	interface you can add/remove paths to recursively scan for media.
"""
import os,sys,dircache,glob

from sqlobject import *
from ID3 import *

class Collection:
	def __init__(self, _debug=False):
		""" Init the sqlite connection and set a cursor. """
		db_filename = os.path.abspath('data.db')
		connection_string = 'sqlite:' + db_filename
		self.conn = connectionForURI(connection_string)
		sqlhub.processConnection = self.conn
		self.paths = []
		if _debug:
			self.debug = True
		else:
			self.debug = False

	def add_path(self, _path):
		""" Add a path to the library, accepts a string which is 
		    the full path of the directory to add"""
		to_add =  Path.select(Path.q.path == _path).count()
		if to_add == 0:
			Path(path=_path)
			self.debug_msg("path: " + _path + " added.")
			return True
		else:
			self.debug_msg("path already exists!")
			return False

	def remove_path(self, _path):
		""" Removes a path from the db, accepts a string which 
		    is the full path """
		pass
	
	def edit_path(self, _path, _new_path):
		""" Edits the path entry matching _path and changing it to 
			_new_path
		"""
		self.debug_msg("editing path: " + _path)
		to_edit =  Path.select(Path.q.path == _path)
		try:
			p = to_edit.getOne()
			self.debug_msg("found the path:" + _path)
			p.path = _new_path
		except SQLObjectNotFound:
			self.debug_msg("no path matched that!")
		except SQLObjectIntegrityError:
				self.debug_msg("found to many paths matching!!!")
		

	def get_path_list(self):
		""" Query the db and return a list of paths. """
		paths = Path.select()
		path_list = []
		for p in paths:
			path_list.append(p.path)
		return path_list
		

	def scan_paths(self):
		""" Scan all paths listed and build the db """
		paths = Path.select()
		for path in paths:
			self.dive(path.path)

	def scan_paths_cb(self, cb):
		""" same as scan_paths but accepts a callback function. If 
			this function is provided, it is called and each time 
			a directory is found. This is here to make the progress 
			bar work in a gtk app.
		"""
		paths = Path.select()
		for path in paths:
			self.dive(path.path, cb)

	def dive(self, _path, cb = None):
		""" Gets a directory list of _path and recursively dives into
			each directory and gets each mp3 file. gets id3 from each mp3 
			file and adds it to the song database.
		"""
		songs = []
		self.debug_msg("Diving into: " + _path)
		if cb:
			cb(_path)
		a = dircache.listdir(_path)
		dircache.annotate(_path, a)
		if a:
			for dir in a:
				if dir.find('/') == -1:
					pass
				else:
					if cb:
						self.dive(_path+dir, cb)
					else:
						self.dive(_path+dir)

		
		os.chdir(_path)
		song_glob =  glob.glob('*.mp3')
		for song in song_glob:
			try:
				songs.append(ID3(_path + song))

			except:
				self.debug_msg("Cant add file!!!")
		for s in songs:
			try:
				Song(filename=s.filename, title=s.title,  album=s.album, 
				     artist=s.artist, track=s.track, year=s.year, genre=s.genre, 
				     comment=str(s.comment))
			except:
				self.debug_msg("Cant add file!!!1")


	def add_song(self, _filename):
		""" add an individual song to the database"""
		pass

	def remove_song(self):
		""" remove track from the database """
		pass

	def create_tables(self):
		""" Create the tables for the dtatbase """
		Path.createTable()
		self.debug_msg("Path table added")
		Song.createTable()
		self.debug_msg("Song table added")
		Artist.createTable()
		self.debug_msg("Artist table created")
		Album.createTable()
		self.debug_msg("Album table created")

	def debug_msg(self, _msg):
		""" if debug is True then print _msg """
		if self.debug:
			print ">>> " + _msg
	
	def get_all_songs(self):
		""" returns a sqlobject.selectresults for the enite database """
		return Song.select()

	def get_all_artists(self):
		return Artist.select()


	def build_artists(self):
		songs = Song.select()
		for s in songs:
			if Artist.select(Artist.q.name == s.artist).count() == 0:
				self.debug_msg("adding artist: " + s.artist)
				Artist(name = s.artist)
			else:
				self.debug_msg("Dulicate artist: " + s.artist)


	def build_albums(self):
		songs = Song.select()
		for s in songs:
			if Album.select(Album.q.name == s.album).count() == 0:
				a = Album(name = s.album)
				artist_fetch = Artist.select(Artist.q.name == s.artist)
				artist_fetch[0].addAlbum(a)
			else:
				self.debug_msg("Duplicate Album")
				
class Path(SQLObject):
	path = StringCol()

	def _set_attr1(self, value):
		path="value"

class Song(SQLObject):
	filename = StringCol()
	title = StringCol()
	album = StringCol()
	artist = StringCol()
	track = StringCol()
	year = StringCol()
	genre= StringCol()
	comment = StringCol()

class Artist(SQLObject):
	name = StringCol()
	albums = RelatedJoin('Album')

class Album(SQLObject):
	name = StringCol()
	artist = RelatedJoin('Artist')

